/*
 * Windy - Level Editor for Isometric Tile-based Games
 * Copyright (C) 2009 Ricardo J. Ricken (Darkl0rd)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#ifndef ISOMETRIC_GRID_HPP
#define ISOMETRIC_GRID_HPP

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include "windy_document.hpp"

enum {
   GridRect_Empty = -1
};

enum {
   GridRect_None = -1,
   GridRect_Up,
   GridRect_Down
};

struct GridRect {
   GridRect():
   upperTile(GridRect_Empty), lowerTile(GridRect_Empty), orient(GridRect_None) {}

   GridRect(int upper, int lower, int orientation):
   upperTile(upper), lowerTile(lower), orient(orientation) {}

   int orient;
   int upperTile;
   int lowerTile;
};

class IsometricGrid
{
public:
   IsometricGrid(WindyDocument &document) : doc(document), invalid_pos(-1, -1)
   {
      map = 0;
      map_len = 0;
      mouse_over = false;
      over = sel = IsometricGrid::invalid_pos;

      init_map();
   }

   ~IsometricGrid() {
      if (map) delete [] map;
   }

   bool valid (const wxPoint &map_coord) {
      return map_coord.x != -1 && map_coord.y != 1;
   }

   bool contains (const wxPoint &c) const {
      return (c.x >= 0) && (c.x < doc.width()) && (c.y >= 0) && (c.y < doc.height()) ?
         true : false;
   }

private:
   void init_map ()
   {
      wxSize sz = doc.size();
      map_len = sz.x + sz.y;

      map = new GridRect[map_len * map_len];

      // depends on the grid orientation (e.g horizontal or vertical)
      int c = sz.x > sz.y ? std::min(sz.y, sz.x) : std::max(sz.y, sz.x);

      // fills info about the tiles
      for (int y = 0; y < sz.y; y++)
         for (int x = 0; x < sz.x; x++)
         {
            int pos = (y + x) * map_len + (x + c - 1 - y);
            int tilenum = y * sz.x + x;

            map[pos].lowerTile = map[pos + 1].lowerTile = tilenum;
            map[pos + map_len].upperTile = map[pos + map_len + 1].upperTile = tilenum;

            map[pos].orient = map[pos + map_len + 1].orient = GridRect_Up;
            map[pos + 1].orient = map[pos + map_len].orient = GridRect_Down;
         }
   }

public:
   GridRect *map;
   int map_len;

   wxRect b_box;
   wxPoint over, sel;

   bool mouse_over;
   const wxPoint invalid_pos;

private:
   WindyDocument &doc;
};

#endif //~ISOMETRIC_GRID_HPP